package service

import (
	"regexp"
	"strings"
	"unicode/utf8"
)

// SearchHighlighter 搜索结果高亮处理器
type SearchHighlighter struct{}

// NewSearchHighlighter 创建搜索高亮处理器实例
func NewSearchHighlighter() *SearchHighlighter {
	return &SearchHighlighter{}
}

// GenerateHighlight 生成高亮显示的内容
func (h *SearchHighlighter) GenerateHighlight(content, query string) string {
	// 简单的高亮生成策略：在查询词周围添加标记
	if query == "" {
		return content
	}
	
	// 将查询词转换为小写，用于不区分大小写的匹配
	lowerQuery := strings.ToLower(query)
	lowerContent := strings.ToLower(content)
	
	// 查找查询词在内容中的位置
	index := strings.Index(lowerContent, lowerQuery)
	if index == -1 {
		return content
	}
	
	// 确保高亮范围不会超出内容长度
	start := index
	end := index + len(query)
	if start < 0 {
		start = 0
	}
	if end > len(content) {
		end = len(content)
	}
	
	// 获取高亮部分
	highlightPart := content[start:end]
	
	// 获取前后文（各50个字符）
	contextStart := start - 50
	if contextStart < 0 {
		contextStart = 0
	}
	contextEnd := end + 50
	if contextEnd > len(content) {
		contextEnd = len(content)
	}
	
	// 确保contextStart和contextEnd位置不破坏UTF-8字符的完整性
	contextStart = h.findNearestUTF8Boundary(content, contextStart)
	contextEnd = h.findNearestUTF8Boundary(content, contextEnd)
	
	// 构建高亮内容
	result := content[contextStart:start] +
		"<mark>" + highlightPart + "</mark>" +
		content[end:contextEnd]
	
	// 添加省略号
	var finalResult strings.Builder
	if contextStart > 0 {
		finalResult.WriteString("...")
	}
	finalResult.WriteString(result)
	if contextEnd < len(content) {
		finalResult.WriteString("...")
	}
	
	return finalResult.String()
}

// GenerateRegexHighlightWithContext 生成带上下文的正则表达式高亮显示的内容
func (h *SearchHighlighter) GenerateRegexHighlightWithContext(content string, regex *regexp.Regexp, matchStart, matchEnd int) string {
	// 确定上下文范围（前后各100个字符）
	contextSize := 100
	start := matchStart - contextSize
	if start < 0 {
		start = 0
	}
	end := matchEnd + contextSize
	if end > len(content) {
		end = len(content)
	}
	
	// 确保start和end位置不破坏UTF-8字符的完整性
	start = h.findNearestUTF8Boundary(content, start)
	end = h.findNearestUTF8Boundary(content, end)
	
	// 构建高亮内容
	var result strings.Builder
	lastPos := start
	
	// 添加省略号
	if start > 0 {
		result.WriteString("...")
	}
	
	// 查找在范围内的所有匹配
	matches := regex.FindAllStringIndex(content[start:end], -1)
	
	for _, match := range matches {
		// 调整位置到原始内容中的位置
		adjustedStart := match[0] + start
		adjustedEnd := match[1] + start
		
		// 添加匹配前的文本
		if adjustedStart > lastPos {
			result.WriteString(content[lastPos:adjustedStart])
		}
		
		// 添加高亮标记
		result.WriteString("<mark>")
		result.WriteString(content[adjustedStart:adjustedEnd])
		result.WriteString("</mark>")
		
		lastPos = adjustedEnd
	}
	
	// 添加剩余文本
	if lastPos < end {
		result.WriteString(content[lastPos:end])
	}
	
	// 添加省略号
	if end < len(content) {
		result.WriteString("...")
	}
	
	return result.String()
}

// findNearestUTF8Boundary 找到最近的UTF-8字符边界
func (h *SearchHighlighter) findNearestUTF8Boundary(content string, pos int) int {
	// 如果位置已经是边界，直接返回
	if pos <= 0 || pos >= len(content) {
		return pos
	}
	
	// 检查当前位置是否是UTF-8字符的起始位置
	if utf8.RuneStart(content[pos]) {
		return pos
	}
	
	// 向前查找最近的UTF-8字符起始位置
	for i := pos - 1; i >= 0; i-- {
		if utf8.RuneStart(content[i]) {
			return i
		}
	}
	
	// 如果找不到，返回0
	return 0
}

// CalculateLineNumber 根据字符位置计算行号
func (h *SearchHighlighter) CalculateLineNumber(content string, pos int) int {
	if pos < 0 || pos >= len(content) {
		return 1 // 默认返回第一行
	}
	
	lineNumber := 1
	for i := 0; i <= pos && i < len(content); i++ {
		if content[i] == '\n' {
			lineNumber++
		}
	}
	return lineNumber
}

// min 返回两个整数中的较小值
func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}